home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 309_01 / cc2.c < prev    next >
Text File  |  1990-03-18  |  14KB  |  537 lines

  1. /*
  2. HEADER:        Small-C source part 2;
  3. FILENAME:    CC2.C;
  4. AUTHORS:    Dieter H. Flunkert;
  5. COMPILERS:Turbo C V2.0 Medium Memory Model;
  6. SYSTEM: MSDOS, modified by Brian Brown, Nov 1989
  7. */
  8. #include <stdio.h>
  9. #include "ccdef.c"
  10.  
  11. /* define external functions */
  12. extern int addglb(), addloc(), addwhile(), amatch(), blanks(), ch(),
  13.   comment(), constexpr(), cout(), debug(), declloc(), defname(),
  14.   defstorage(), delwhile(), doexpression(), dumplits(), endst(), entry(),
  15.   errrpt(), findglb(), findloc(), gch(), getlabel(), getint(), illname(),
  16.   inbyte(), inchar(), inline(), junk(), jump(), kill(), match(), modstk(),
  17.   multidef(), needbrack(), nextsym(), nl(), number(), outbyte(), outdec(),
  18.   outstr(), postlabel(), prelabel(), printlabel(), putint(),
  19.   readwhile(), ret(), sout(), streq(), sw(), symname(), tab(), test();
  20.  
  21. /*  external variables */
  22. extern int argstk, ctext, cmode, DEFDEBUG, declared, declstat, eof,
  23.   first_func,lastst, litlab, litptr, lptr, monitor,
  24.   nogo, noloc, ncmp, *startcomp, statlab, stdecl, stkp,
  25.   stlab, swactive, swdefault, *swnext, *swend, asmtype;
  26.  
  27. extern char *cptr, *cptr2, line[linesize], *locptr, *glbptr, *statptr,symtab[symtbsz];
  28.  
  29. /* Get required array size, invoked when declared variable is followed
  30.    by "[",  this routine makes subscript the absolute size of the array. */
  31. needsub()
  32. {
  33.  int num[1];
  34.  if(match("]"))return (0); /* null size */
  35.  if (number(num)==0) /* go after a number */
  36.   {errrpt("must be constant"); /* it isn't */
  37.   num[0]=1;  /* so force one */
  38.   }
  39.  if (num[0]<0)
  40.   {errrpt("negative size illegal");
  41.   num[0]=(-num[0]);
  42.   }
  43.  needbrack("]");  /* force single dimension */
  44.  return (num[0]);  /* and return size */
  45.  }
  46.  
  47. /* Begin a function  */
  48. /* Called from "parse" this routine tries to make a function out of what follows. */
  49. newfunc(class)
  50. int class;
  51. {  /* next lines added by dieter flunkert 23 jan 1986 */
  52.   int argtop;  /* top of argument stack */
  53.   char n[namesize],*ptr;
  54. #ifdef STGOTO
  55.   nogo=noloc=0;
  56. #endif
  57.   if(monitor)
  58.   {
  59.     cout('\n',stderr);
  60.     sout(line,stderr);
  61.   }
  62.   if (symname(n)==0)
  63.   {
  64.     errrpt("illegal function or declaration");
  65.     kill(); /* invalidate line */
  66.     return;
  67.   }
  68.  if(ptr=findglb(n)) /* already in symbol table ? */
  69.   {
  70.     if(ptr[ident]!=function)  multidef(n);
  71.     /* already variable by that name */
  72.     else if(ptr[offset]==function)multidef(n);
  73.     /* already function by that name */
  74.    else ptr[offset]=function;
  75.     /* otherwise we have what was earlier*/
  76.     /*  assumed to be a function */
  77.   }
  78.  /* if not in table, define as a function now */
  79.  else addglb(n,function,cint,function);
  80.  /* we had better see open paren for args... */
  81.  if(match("(")==0)errrpt("missing open paren");
  82. /* next lines added by dieter flunkert 23 jan 1986 */
  83.  if(first_func) {
  84.    defname(n);  /* define name of asm module */
  85.    first_func = 0;
  86.  }
  87.  entry(n, class);
  88.  if(DEFDEBUG) debug(n);
  89.      /* ** Clear local stack pointer rev. 1P */
  90.  locptr = startloc; /* ** 2 lines inserted  rev. 1P */
  91.  argstk=0;  /* init arg count */
  92.  while(match(")")==0) /* then count args */
  93.   /* any legal name bumps arg count */
  94.   {if(symname(n)) /* **+ Modification  rev. 1P */
  95.    { if (findloc(n)) multidef(n);
  96.    else { addloc(n, 0, 0, argstk);
  97.     argstk = argstk + 2;
  98.    }
  99.   }  /* **- End of modification rev. 1P */
  100.   else{errrpt("illegal argument name");junk();}
  101.   blanks();
  102.   /* if not closing paren, should be comma */
  103.   if(streq(line+lptr,")")==0)
  104.    {if(match(",")==0)
  105.    errrpt("expected comma");
  106.    }
  107.   if(endst())break;
  108.   }
  109. /* ** Next line deleted      rev. 1P */
  110. /* ** locptr=startloc; ** */ /* "clear" local symbol table*/
  111.  stkp=0;   /* preset stack ptr */
  112. /* next line added by dieter flunkert 23 jan 1986 */
  113.  argtop=argstk; /* save top of argument stack */
  114.  while(argstk)
  115.   /* now let user declare what types of things */
  116.   /* those arguments were */
  117.   {if(amatch("char",4)){getarg(argtop,cchar);ns();}
  118.   else if(amatch("int",3)){getarg(argtop,cint);ns();}
  119.   else{errrpt("wrong number args");break;}
  120.   }
  121.  if(statement()!=streturn) /* do a statement, but if */
  122.     /* it's a return, skip */
  123.     /* cleaning up the stack */
  124.   {modstk(0);
  125.   ret();
  126.   }
  127.  stkp=0;   /* reset stack ptr again */
  128.  locptr=startloc; /* deallocate all locals */
  129.  if(litptr) {     /* dump literal pool */
  130.     prelabel(litlab);
  131.     dumplits(1);
  132.     litlab=getlabel();
  133.   }
  134. }
  135.  
  136. /* Declare argument types, called from "newfunc" this routine adds an entry
  137.    in the local symbol table for each named argument. argtop is not allowed
  138.    to change value. This was the case if a function had a declaration like:
  139.    int i; char c; */
  140.  
  141. getarg(argtop,t)  /* t = cchar or cint */
  142. int argtop,t;
  143. {
  144.  int j, legalname, address;
  145.  char n[namesize], c, *argptr;
  146.  while(1)
  147.   {if(argstk==0)return; /* no more args */
  148.   if(match("*"))j=pointer;
  149.    else j=variable;
  150.   if((legalname = symname(n)) == 0) illname();
  151.   if(match("[")) /* pointer ? */
  152.   {
  153.      while(inbyte()!=']')     /* it is a pointer, so skip all stuff between "[]" */
  154.      if(endst())break;
  155.     j=pointer;  /* add entry as pointer */
  156.   }
  157.   if (legalname) {
  158.    if (argptr = findloc(n)) {
  159.    /*  Add in details of the type and address of the name  */
  160.    argptr[ident] = j;
  161.    argptr[type] = t;
  162.    address = argtop - (argptr[offset] + (argptr[offset+1]<<8));
  163.    putint(address, argptr+offset, offsize);
  164.    }
  165.   else errrpt("Expected argument name");
  166.   }
  167.   argstk=argstk-2; /* cnt down */
  168.   if (endst()) return;
  169.   if (match(",") == 0) errrpt("expected comma");
  170.   }
  171. }
  172.  
  173. /* statement parser, called whenever syntax requires a statement this
  174.    routine performs that statement and returns a number telling which one */
  175. statement()
  176. {
  177.   int class;
  178.   if ((ch==0) && (eof)) return;
  179.   if(amatch("static",6)) {
  180.    class=statik;
  181.    if(++stdecl == 1)  /* there are static variables */
  182.        jump(stlab=getlabel()); /* skip static declarations */
  183.   }
  184.   else class=stkloc;
  185.   if(amatch("char",4))  {declloc(cchar,class);ns();}
  186.   else if(amatch("int",3))   {declloc(cint,class);ns();}
  187.   else {
  188.     if(stdecl > 0) {
  189.       postlabel(stlab);
  190.       stdecl = 0;
  191.     }
  192.     if(declared >= 0) {
  193. #ifdef STGOTO
  194.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  195. #endif
  196.       stkp=modstk(stkp - declared);
  197.       declared = -1;
  198.       }
  199.     if(match("{"))               compound();
  200.     else if(amatch("if",2))      {doif();lastst=stif;}
  201.     else if(amatch("while",5))   {dowhile();lastst=stwhile;}
  202.     else if(amatch("do",2))      {dodo();lastst=STDO;}
  203.     else if(amatch("for",3))     {dofor();lastst=STFOR;}
  204.     else if(amatch("switch",6))  {doswitch();lastst=STSWITCH;}
  205.     else if(amatch("case",4))    {docase();lastst=STCASE;}
  206.     else if(amatch("default",7)) {dodefault();lastst=STDEF;}
  207. #ifdef STGOTO
  208.     else if(amatch("goto", 4))   {dogoto(); lastst=STGOTO;}
  209.     else if(dolabel())           lastst=STLABEL;
  210. #endif
  211.     else if(amatch("return",6))  {doreturn();ns();lastst=streturn;}
  212.     else if(amatch("break",5))   {dobreak();ns();lastst=stbreak;}
  213.     else if(amatch("continue",8)){docont();ns();lastst=stcont;}
  214.     else if(match(";"))          ;
  215.     else if(match("#asm"))       {doasm();lastst=stasm;}
  216.     else if(match("#data"))      {dodata(); lastst=stdata;}
  217.     else if(match("#const"))     {doconst(); lastst=stconst;}
  218.     else if(match("#code"))      {docode(); lastst=stcode;}
  219.     else                         {doexpression();ns();lastst=stexp;}
  220.     }
  221.   return lastst;
  222.   }
  223.  
  224. dodo() {
  225.   int wq[4], top;
  226.   addwhile(wq);
  227.   prelabel(top=getlabel());
  228.   statement();
  229.   needbrack("while");
  230.   prelabel(wq[wqloop]);
  231.   test(wq[wqlab],YES);
  232.   jump(top);
  233.   prelabel(wq[wqlab]);
  234.   delwhile();
  235.   ns();
  236. }
  237.  
  238. dofor() {
  239.   int wq[4], lab1, lab2;
  240.   addwhile(wq);
  241.   lab1=getlabel();
  242.   lab2=getlabel();
  243.   needbrack("(");
  244.   if(match(";")==0) {
  245.     doexpression();            /* expr 1 */
  246.     ns();
  247.     }
  248.   prelabel(lab1);
  249.   if(match(";")==0) {
  250.     test(wq[wqlab],NO); /* expr 2 */
  251.     ns();
  252.     }
  253.   jump(lab2);
  254.   prelabel(wq[wqloop]);
  255.   if(match(")")==0) {
  256.     doexpression();            /* ex